// bsp2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct List;
void parseKeyFile(char*, List*);
void swapElements(List*, List*);
List* sort(List*);
int getLength(List*);
void printList(List*);
char* uncompress(char*, char*);
char* getTextAt(int, List*);

struct List
{
	int key;
	char text[20];
	int nr;
	List *next;
	List *prev;
};


int main(int argc, char* argv[])
{
	char *key = argv[2];
	char *file = argv[1];
	
	char *result = uncompress(file, key);

	printf("%s", result);

	getchar();	
}

char* uncompress(char *filename, char *key)
{
	char *uncompressed;
	//get list
	List *list = (List*) malloc(sizeof(List));
	parseKeyFile(key, list);
	list = sort(list);
	//get text file
	FILE *fp = fopen(filename, "r");
	

	if(fp != NULL)
	{
		// obtain file size:
		fseek (fp , 0 , SEEK_END);
		int lSize = ftell (fp);
		rewind (fp);
		//save file content to char array
		char *text = (char*)malloc(sizeof(char)*lSize);
		fread(text, 1, lSize, fp);

		//get number of %
		int count = 0;
		int i = 0;
		while(text[i] != '\0') 
		{
			if(text[count] == '%') count++;
			i++;
		}
		//estimate output file length. assumption: longest word in list is 20 chars long
		uncompressed = (char*)malloc(sizeof(char)*(lSize + 20*count)); 

		int j = 0;
		for(int i = 0; i <= lSize; i++)
		{
			//copy each sign to output text
			if(text[i] != '%')
			{
				uncompressed[j] = text[i];
				j++;
			}
			//% found
			else
			{
				//get number
				int nr = atoi(&text[i+1]);

				//get text of list element with key = nr
				char *string = getTextAt(nr, list);
				for(int z = 0; z < strlen(string); z++)
				{
					uncompressed[j] = string[z];
					j++;
				}
				i++;
			}
			if(i == lSize)uncompressed[j-1] = '\0';
		}
	}
	return uncompressed;
}

char* getTextAt(int nr, List *list)
{
	static char text[20];
	while(list != NULL)
	{
		if(list->key == nr)
		{
			strcpy(text, list->text);
			return text;
		}
			
		list = list->next;
	}
	return text;
}

void parseKeyFile(char * fileName, List *root)
{
	//initialize root list element
	root->prev = NULL;
	root->next = NULL;
	List *tmp = root;

	//open file
	FILE *fp = fopen("key.txt", "r");
	if(fp != NULL)
	{
		//get key, text, and nr from line
		int key, nr;
		char *text;
		char line[100];
		while((fscanf(fp, "%s\n", line))!=EOF){	
			//get key, text and nr from current line
			key = atoi(strtok(line, ":"));
			text = strtok(NULL, ":");
			nr = atoi(strtok(NULL, " "));
			
			tmp->key = key;
			strcpy(tmp->text, text);
			tmp->nr = nr;
			tmp->next = (List *) malloc(sizeof(List));
			tmp->next->prev = tmp;
			tmp = tmp->next;
			tmp->next = NULL;
				
		}
		fclose(fp);
	}
}

//swaps two adjacent elements of the list
//el1 has to be the predecessor of el2
void swapElements(List *el1, List *el2)
{
	
	if(el1->prev != NULL)el1->prev->next = el2;
	if(el2->next != NULL)el2->next->prev = el1;

	el1->next = el2->next;
	el2->prev = el1->prev;
	el2->next = el1;
	el1->prev = el2;	
}

int getLength(List *list)
{
	int length = 0;
	while(list->next != NULL)
	{
		length++;
		list = list->next;
	}
	return length;
}

void printList(List *list)
{
	while(list != NULL)
	{
		printf("%d %s %d\n", list->key, list->text, list->nr);
		list = list->next;
	}
}

List* sort(List *root)
{
	for(int i = 0; i < getLength(root); i++)
	{
		List *tmp = root;
		for(int j = 0; j < getLength(root)-i; j++)
		{
			//printf("%s - %s ---- ", root->text, root->next->text);
			if(tmp->nr >= tmp->next->nr)
			{
				swapElements(tmp, tmp->next);
				if(tmp->prev->prev == NULL) root = tmp->prev;
			}else 
			{
				tmp = tmp->next;
				
			}
		}
	}
	return root->next;
}

